#!/usr/bin/env python3
"""
审计日志服务
"""

from datetime import datetime
from typing import Any

from sqlalchemy.ext.asyncio.session import AsyncSession
from sqlalchemy.future import select

from app.models.audit_log import AuditLog


async def audit_log(
    db: AsyncSession,
    operator: str,
    operation_type: str,
    operation_target: str,
    operation_details: dict[str, Any] | None = None,
    ip_address: str | None = None,
    user_agent: str | None = None,
    success: bool = True,
    error_message: str | None = None,
    related_visitor_id: int | None = None,
    related_qrcode: str | None = None,
) -> AuditLog:
    """
    记录审计日志

    Args:
        db: 数据库会话
        operator: 操作人
        operation_type: 操作类型
        operation_target: 操作目标
        operation_details: 操作详情
        ip_address: IP地址
        user_agent: 用户代理
        success: 是否成功
        error_message: 错误信息
        related_visitor_id: 关联访客ID
        related_qrcode: 关联二维码

    Returns:
        AuditLog: 创建的审计日志记录
    """
    audit_log = AuditLog()
    audit_log.operator = operator
    audit_log.operation_type = operation_type
    audit_log.operation_target = operation_target
    audit_log.operation_details = operation_details
    audit_log.ip_address = ip_address
    audit_log.user_agent = user_agent
    audit_log.success = success
    audit_log.error_message = error_message
    audit_log.operation_time = datetime.now()
    audit_log.related_visitor_id = related_visitor_id
    audit_log.related_qrcode = related_qrcode

    db.add(audit_log)  # type: ignore[attr-defined]
    await db.commit()
    await db.refresh(audit_log)

    return audit_log


async def get_audit_logs(
    db: AsyncSession,
    page: int = 1,
    page_size: int = 20,
    operator: str | None = None,
    operation_type: str | None = None,
    start_time: datetime | None = None,
    end_time: datetime | None = None,
) -> tuple[list[AuditLog], int]:
    """
    获取审计日志列表

    Args:
        db: 数据库会话
        page: 页码
        page_size: 每页数量
        operator: 操作人过滤
        operation_type: 操作类型过滤
        start_time: 开始时间
        end_time: 结束时间

    Returns:
        tuple[list[AuditLog], int]: 日志列表和总数
    """
    query = select(AuditLog)

    if operator:
        query = query.where(AuditLog.operator == operator)
    if operation_type:
        query = query.where(AuditLog.operation_type == operation_type)
    if start_time:
        query = query.where(AuditLog.operation_time >= start_time)
    if end_time:
        query = query.where(AuditLog.operation_time <= end_time)

    from typing import Any
    from sqlalchemy.sql.elements import ColumnElement
    
    # 计算总数
    where_clauses: list[ColumnElement[Any]] = []
    if query.whereclause is not None:
        where_clauses.append(query.whereclause)
    
    total_query = select(AuditLog)
    if where_clauses:
        total_query = total_query.where(*where_clauses)
    
    total_result = await db.execute(total_query)
    total = len(total_result.scalars().all())

    # 获取分页数据
    query = query.order_by(AuditLog.operation_time.desc())
    query = query.offset((page - 1) * page_size).limit(page_size)

    result = await db.execute(query)
    logs = result.scalars().all()

    return list(logs), total
